package com.sos.application
{
	
	
	import com.deadreckoned.assetmanager.AssetManager;
	import com.deadreckoned.assetmanager.events.AssetEvent;
	import com.sos.Shared;
	import com.sos.Version;
	import com.sos.VersionType;
	import com.sos.comm.Call;
	import com.sos.comm.CallErrorEvent;
	import com.sos.comm.CallEvent;
	import com.sos.comm.CallFactory;
	import com.sos.comm.CallFailEvent;
	import com.sos.comm.CallFailType;
	import com.sos.comm.CallSuccessEvent;
	import com.sos.config.Configuration;
	import com.sos.config.ConfigurationManager;
	import com.sos.config.ConfigurationManagerEvent;
	import com.sos.core.User;
	import com.sos.core.cards.Card;
	import com.sos.core.cards.CardManager;
	import com.sos.core.cards.CardManagerEvent;
	import com.sos.core.cards.CardType;
	import com.sos.core.cards.Collection;
	import com.sos.core.cards.Deck;
	import com.sos.core.game.client.GameClient;
	import com.sos.core.game.client.GameClientOptions;
	import com.sos.core.game.engine.GameEngine;
	import com.sos.logging.Logger;
	import com.sos.utils.ErrorUtils;
	import com.sos.utils.StringUtils;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.external.ExternalInterface;
	import flash.net.URLVariables;
	import flash.system.Capabilities;
	import flash.system.Security;
	

	public class FlashApplication
	{

		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------
		
		// Logging
		public static const		LOG_MARKER:String					= "APP > ";
		public static const		DEBUG_KEY:String					= "sos.application";
		
		// Application version
		public static const		NAME:String							= "Schools Of Soccer";
		public static const		VERSION:Version						= new Version(VersionType.ALPHA,
																				  0, 			// major
																				  4, 			// minor
																				  0, 			// release
																				  "48",			// build
																				  "Franco");	// codename
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		// Flags
		private static var _init:Boolean;
		// Data
		private static var _params:Object;
		private static var _config:Configuration;
		private static var _user:User;
		private static var _collection:Collection;
		private static var _ui:DisplayObject;
		private static var _client:GameClient;
		private static var _engine:GameEngine;
		// Init
		private static var _initStep:int;
		private static var _initSteps:Vector.<Function>;
		// Event dispatcher 
		private static var _dispatcher:EventDispatcher;
		
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTOR
		// -------------------------------------------------------------------------------
		
		// Static constructor
		{
			// Init
			_initStep	= Shared.INVALID_INDEX;
			_initSteps	= new Vector.<Function>();
			_dispatcher = new EventDispatcher();
			// Builds the init steps list
			_initSteps.push(initStep01_Config);
			_initSteps.push(initStep02_Logger);
			_initSteps.push(initStep03_System);
			_initSteps.push(initStep04_CardData);
			_initSteps.push(initStep05_Assets);
			_initSteps.push(initStep06_UI);
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------
		
		public static function get isInit():Boolean
		{
			return _init;
		}
		
		public static function get isLocal():Boolean
		{
			checkInit();
			// Verifica se l'url locale contiene il protocollo di un file locales
			var re:RegExp = new RegExp("file://");
			return re.test(baseUrl);
		}
		
		public static function get isDebug():Boolean
		{
			checkInit();
			return _config.debugOptions.enabled;
		}
		
		public static function get isUserLogged():Boolean
		{
			checkInit();
			return _user.isLoggedIn;
		}
		
		public static function get ui():DisplayObject
		{
			return _ui;
		}
		
		public static function get baseUrl():String
		{
			checkInit();
			return _ui.loaderInfo.url;
		}
		
		// LT_TODO: probabilmente non serve esporlo
		public static function get client():GameClient
		{
			return _client;
		}
		
		public static function get engine():GameEngine
		{
			return _engine;
		}
		
		public static function get config():Configuration
		{
			checkInit();
			return _config;
		}	
		
		public static function get user():User
		{
			checkInit();
			return _user;
		}

		public static function get collection():Collection
		{
			checkInit();
			return _collection;
		}

		public static function get hasCollection():Boolean
		{
			checkInit();
			return _collection.loaded;
		}

		
		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------
		
		// Initialization
		
		private static function checkInit():void
		{
			if (!isInit) throwNotInitError();
		}
		
		private static function initBegin():void
		{
			// Trace
			traceMessage(["INIT > BEGIN"]);
			// Dispatch EVENT_INIT_BEGIN event
			dispatchApplicationInitBegin();
			// Resets the step
			_initStep = Shared.INVALID_INDEX;
			// starts the initalization
			initNextStep();
		}
		
		private static function initNextStep():void
		{
			try
			{
				// Check init steps
				if (_initSteps.length > _initStep)
				{
					// Trace
					traceMessage(["INIT > STEP " + (_initStep + 1)]);
					// Increment and executes the next step
					_initStep++;
					_initSteps[_initStep]();
				}
				else initEnd();
			}
			catch (e:Error)
			{
				var message:String = "FlashApplication init unexpected error!";
				// Log initialization error if the logger is initialized
				if (Logger.isInit) Logger.error(message, e);
				else
				{
					// Compose the message
					var messages:Array = new Array();
					messages.push(message + " " + + e.message);
					messages.push("");
					messages.push(ErrorUtils.toArray(e));
					// Trace the error
					traceError(messages);
				}
				// Dispatch EVENT_ERROR event
				dispatchApplicationError(message, e);
			}
		}
		
		private static function initEnd():void
		{
			// Initialized flag
			_init = true;
			// Trace
			traceMessage(["INIT > END"]);
			// Dispatch EVENT_INIT_END event
			dispatchApplicationInitEnd();
			// Dispatch EVENT_START event
			dispatchApplicationStart();
		}
		
		private static function initFailed(message:String, error:Error = null):void
		{
			// Compose the message
			var messages:Array = new Array();
			messages.push(message);
			if (error != null)
			{
				messages.push("");
				messages.push(ErrorUtils.toArray(error));	
			}
			// Trace the error
			traceError(messages);
			// Dispatch EVENT_ERROR event
			dispatchApplicationError("Initialization failed: " + message, error);
		}
		
		// Initialization function handlers
		
		private static function initStep01_Config():void
		{
			try
			{
				// Retrieve the url parameters i 
				var vars:URLVariables = new URLVariables();
				if (ExternalInterface.available)
				{	
					// Retrieve the querystring
					var querystring:String = ExternalInterface.call("ExternalInterface_getUrlQuerystring");
					// Retrieve the querystring using the javascript function
					if (!StringUtils.isEmpty(querystring)) vars.decode( querystring.substr(1) );
				}
				// Configuration url
				var url:String = "http://striptemple.com/sostcg/TestFlash/config/soccertcg.config.xml";
				if (vars.hasOwnProperty("c"))
				{
					url = StringUtils.substitute("http://striptemple.com/sostcg/TestFlash/config/soccertcg.config.{0}.xml", vars.c);				
				}
				// ConfigurationManager
				var configurationManager:ConfigurationManager = new ConfigurationManager();
				configurationManager.addEventListener(ConfigurationManagerEvent.EVENT_LOAD_COMPLETED, 	configManagerLoadCompleted);
				configurationManager.addEventListener(ConfigurationManagerEvent.EVENT_LOAD_FAILED, 		configManagerLoadFailed);
				configurationManager.load(url);
			}
			catch (error:Error)
			{
				// Unexpected error, init failed
				initFailed("Configuration loading in error, " + error.message, error);
			}
		}
		
		private static function initStep02_Logger():void
		{
			try
			{
				// Init the logger
				Logger.init(_config.debugOptions, _config.logOptions);
				// Init next step
				initNextStep();
			} 
			catch(error:Error) 
			{
				// Unexpected error, init failed
				initFailed("Logger init in error, " + error.message, error);
			}
		}
		
		private static function initStep03_System():void
		{
			try
			{
				// Data init
				_user		= new User();
				_collection	= new Collection();
				// GameClient init
				_client = new GameClient(new GameClientOptions());
				// GameEngine init
				_engine = new GameEngine(_client, _config.gameOptions);
				// Init next step
				initNextStep();
			} 
			catch(error:Error) 
			{
				// Unexpected error, init failed
				initFailed("System data init in error, " + error.message, error);
			}
		}
		
		private static function initStep04_CardData():void
		{
			try
			{
				// CardManager loading
				var cardManager:CardManager = CardManager.getCardManager();
				cardManager.addEventListener(CardManagerEvent.EVENT_LOAD_COMPLETED, cardManagerLoadCompleted);
				cardManager.addEventListener(CardManagerEvent.EVENT_LOAD_FAILED, 	cardManagerLoadFailed);
				cardManager.load();
			} 
			catch(error:Error) 
			{
				// Unexpected error, init failed
				initFailed("Card data loading in error, " + error.message, error);
			}
		}
		
		private static function initStep05_Assets():void
		{
			try
			{
				/*
				// Setup asset manager
				var assetManager:AssetManager = AssetManager.getInstance();
				assetManager.addEventListener(AssetEvent.QUEUE_START, 	 assetManagerQueueStart);
				assetManager.addEventListener(AssetEvent.QUEUE_COMPLETE, assetManagerQueueComplete);
				// Add fixed assets
				assetManager.add("img/actionCards/ACBlank.gif", 			{ id: "ACBlank" } );
				assetManager.add("img/actionCards/small_ACBlank.gif", 		{ id: "s_ACBlank" } );
				assetManager.add("img/actionCards/acAttack.gif", 			{ id: "acAttack" } );
				assetManager.add("img/actionCards/small_acAttack.gif", 		{ id: "s_acAttack" } );
				assetManager.add("img/actionCards/acPunk.gif", 				{ id: "acPunk" } );
				assetManager.add("img/actionCards/small_acPunk.gif", 		{ id: "s_acPunk" } );
				assetManager.add("img/actionCards/acPlaymaking.gif", 		{ id: "acPlaymaking" } );
				assetManager.add("img/actionCards/small_acPlaymaking.gif", 	{ id: "s_acPlaymaking" } );
				assetManager.add("img/actionCards/acDefense.gif", 			{ id: "acPlaymaking" } );
				assetManager.add("img/actionCards/small_acDefense.gif", 	{ id: "s_acDefense"});
				// LT_TODO: loop sulle carte caricate con il CardManager e aggiunta degli asset da caricare in base al tipo di carta
				
				var cardManager:CardManager = CardManager.getCardManager();
				for (var i:int = 0; cardManager.count; i++)
				{
					var card:Card = cardManager.getCard(i);
					switch (card.type)
					{
						case CardType.ACTION:
							assetManager.add('img/actionCards/' 		+ _playerImageList[i] + '.gif', { id: card.image });
							assetManager.add('img/actionCards/small_'	+ _playerImageList[i] + '.gif', { id: "s_" + card.image });					
							break;
						case CardType.PLAYER:
						case CardType.GOALKEEPER:
							assetManager.add('img/players/' 			+ _playerImageList[i] + '.gif', { id: card.image });
							assetManager.add('img/players/small_'		+ _playerImageList[i] + '.gif', { id: "s_" + card.image });
							break;
					}
				}
				// Loads assets
				assetManager.load();
				*/
				// Init next step
				initNextStep();
			} 
			catch(error:Error) 
			{
				// Unexpected error, init failed
				initFailed("Assets loaing in error, " + error.message, error);
			}
		}
		
		private static function initStep06_UI():void
		{
			try
			{
				// LT_TODO: UI Init
				
				// Init next step
				initNextStep();
			} 
			catch(error:Error) 
			{
				// Compose the message
				var messages:Array = new Array();
				messages.push("UI init failed: " + error.message);
				messages.push("");
				messages.push(ErrorUtils.toArray(error));
				// Trace the error
				traceError(messages);
				// Dispatch EVENT_ERROR event
				dispatchApplicationError("Logger initialization failed", error);
			}
		}
		
		// Data methods
		
		private static function setupUserData(userData:Object, collectionData:Object, deckListData:Object, activeDeckData:Object):void
		{
			// User data loading
			_user.load(userData);
			// Collection loading
			_collection.load(collectionData);
			// Decks list creation 
			var decks:Array = deckListData.list;
			// Active deck reference
			var activeDeck:Deck = null;
			// Loop over definitions
			for (var i:int = 0; i<decks.length; i++)
			{
				// Deck creation
				var deckData:Object = decks[i];
				var deck:Deck = _collection.createNewDeck(deckData.id, deckData.name);
				// Sets the active deck
				if (deckData.active == 1) activeDeck = deck;
			}
			// Load the current active deck
			activeDeck.load(activeDeckData);
			// Set the active deck
			_collection.activeDeck = activeDeck;
			// INFO > User login
			Logger.info("User {0} login!", _user.username);
		}
				
		// Event handling methods
		
		private static function dispatchEvent(event:Event):Boolean
		{
			return _dispatcher.dispatchEvent(event);
		}
		
		private static function dispatchApplicationStart():void
		{
			_dispatcher.dispatchEvent(new FlashApplicationEvent(FlashApplicationEvent.EVENT_START));
		}
		
		private static function dispatchApplicationInitBegin():void
		{
			_dispatcher.dispatchEvent(new FlashApplicationEvent(FlashApplicationEvent.EVENT_INIT_BEGIN));
		}
		
		private static function dispatchApplicationInitEnd():void
		{
			_dispatcher.dispatchEvent(new FlashApplicationEvent(FlashApplicationEvent.EVENT_INIT_BEGIN));
		}
		
		private static function dispatchApplicationInitStepBegin(message:String, executed:int, total:int):void
		{
			_dispatcher.dispatchEvent(new FlashApplicationInitEvent(FlashApplicationEvent.EVENT_INIT_STEP_BEGIN, message, executed, total));
		}
		
		private static function dispatchApplicationInitStepEnd(message:String, executed:int, total:int):void
		{
			_dispatcher.dispatchEvent(new FlashApplicationInitEvent(FlashApplicationEvent.EVENT_INIT_STEP_END, message, executed, total));
		}
		
		private static function dispatchApplicationLogin():void
		{
			_dispatcher.dispatchEvent(new FlashApplicationEvent(FlashApplicationEvent.EVENT_LOGIN));
		}
		
		private static function dispatchApplicationLoginFailed(message:String):void
		{
			_dispatcher.dispatchEvent(new FlashApplicationEvent(FlashApplicationEvent.EVENT_LOGIN_FAILED, message));
		}
		
		private static function dispatchApplicationLogout(message:String = ""):void
		{
			_dispatcher.dispatchEvent(new FlashApplicationEvent(FlashApplicationEvent.EVENT_LOGOUT, message));
		}
		
		private static function dispatchApplicationError(message:String, error:Error = null):void
		{
			_dispatcher.dispatchEvent(new FlashApplicationErrorEvent(message, error));
		}
		
		// Utility methods
		
		private static function formatMessage(message:String = "", pad:Boolean = false):String
		{
			return Logger.format(message, pad);
		}
		
		private static function traceApplication():void
		{
			// Creates the messages
			var messages:Array = new Array();
			messages.push("");
			messages.push(formatMessage("", true));
			messages.push(formatMessage(com.sos.application.FlashApplication.NAME));
			messages.push(formatMessage("Version {0}"), com.sos.application.FlashApplication.VERSION.toString());
			messages.push(formatMessage("Player: {0} (type: {1}) {2}"), Capabilities.version, Capabilities.playerType, Capabilities.isDebugger ? "DEBUG" : "");
			messages.push(formatMessage("Sandbox: {0}"), Security.sandboxType);
			messages.push(formatMessage("", true));
			// Use the logger if is initialized, otherwise uses trace() function
			if (Logger.isInit)
			{
				for (var i:int=0; i<messages.length; i++) Logger.info(messages[i]);
			}
			else
			{
				traceMessage(messages);
			}
		}
		
		private static function traceMessage(messages:Array):void
		{
			trace("");
			trace(formatMessage("FlashApplication MESSAGE", true));
			for (var i:int = 0; i < messages.length; i++) trace(formatMessage(messages[i]));
			trace(formatMessage("", true));
			trace("");			
		}
		
		private static function traceError(messages:Array):void
		{
			trace("");
			trace(formatMessage("FlashApplication ERROR", true));
			for (var i:int = 0; i < messages.length; i++) trace(formatMessage(messages[i]));
			trace(formatMessage("", true));
			trace("");
		}
		
		private static function throwNotInitError():void
		{
			throw new Error("FlashApplication is not initialized!");
		}
		
		// Login Call event handler
		
		private static function loginCallSuccessHandler(e:CallSuccessEvent):void
		{
			try
			{
				// Retrieve the results
				var raw_user:Object 		= e.call.data["user"];
				var raw_collection:Object 	= e.call.data;
				var raw_deck_list:Object 	= e.call.data["deckList"];
				var raw_deck:Object 		= e.call.data["activeDeck"];
				// If the is already logger, perform the user logout 
				if (_user.isLoggedIn)
				{
					logout(false);
				}
				// Executes the user login
				setupUserData(raw_user, raw_collection, raw_deck_list, raw_deck);
				// Dispatch EVENT_LOGIN event
				dispatchApplicationLogin();
				// DEBUG > User logout
				if (Logger.canDebug(DEBUG_KEY)) Logger.info("User {0} login!", _user.username);
			}
			catch (error:Error)
			{
				// Error message
				var msg:String = "loginCallSuccessHandler() unexpected error";
				// DEBUG > Unexpected error
				Logger.error(LOG_MARKER + msg, error);
				// Dispatch EVENT_ERROR event
				dispatchApplicationError(msg, error);
			}
		}
		
		private static function loginCallErrorHandler(e:CallErrorEvent):void
		{
			try
			{
				// Build error message
				var message:String = "Login failed: " + e.call.error.message;
				// DEBUG > User logout
				if (Logger.canDebug(DEBUG_KEY)) Logger.debug("User login call in error: ", message);
				// Dispatch EVENT_LOGIN_FAILED event
				dispatchApplicationLoginFailed(message);
			}
			catch (error:Error)
			{
				// Error message
				var msg:String = "loginCallErrorHandler() unexpected error";
				// DEBUG > Unexpected error
				Logger.error(LOG_MARKER + msg, error);
				// Dispatch EVENT_ERROR event
				dispatchApplicationError(msg, error);
			}
		}
		
		private static function loginCallFailHandler(e:CallFailEvent):void
		{
			try
			{
				// Build error message
				var message:String = "Call '" + e.call.url + "' failed: " + e.call.error.message + " [type:" + CallFailType.getById(e.call.error.code ).name + "]";
				// DEBUG > User logout
				if (Logger.canDebug(DEBUG_KEY)) Logger.debug("User login call failed: ", message);
				// Dispatch EVENT_LOGIN_FAILED event
				dispatchApplicationLoginFailed(message);
			}
			catch (error:Error)
			{
				// Error message
				var msg:String = "loginCallErrorHandler() unexpected error";
				// DEBUG > Unexpected error
				Logger.error(LOG_MARKER + msg, error);
				// Dispatch EVENT_ERROR event
				dispatchApplicationError(msg, error);
			}
		}
		
		// ConfigurationManger event handlers
		
		private static function configManagerLoadCompleted(e:ConfigurationManagerEvent):void
		{
			try
			{
				// saves the configuration
				_config = e.configuration;
				// Init next step
				initNextStep();
			}
			catch (error:Error)
			{
				// Error message
				var msg:String = "configManagerLoadCompleted() unexpected error";
				// DEBUG > Unexpected error
				Logger.error(LOG_MARKER + msg, error);
				// Dispatch EVENT_ERROR event
				dispatchApplicationError(msg, error);
			}
		}
		
		private static function configManagerLoadFailed(e:ConfigurationManagerEvent):void
		{
			try
			{
				// Dispatch EVENT_ERROR event
				dispatchApplicationError("Initialization failed, ConfigurationManager loading failed: " + e.message);
			}
			catch (error:Error)
			{
				// Dispatch EVENT_ERROR event
				dispatchApplicationError("configManagerLoadFailed() unexpected error", error);
			}
		}	
		
		// CardManager event handlers
		
		private static function cardManagerLoadCompleted(e:CardManagerEvent):void
		{
			// DEBUG > Cardmanager load complete
			if (Logger.canDebug(DEBUG_KEY)) Logger.debug("CardManager loaded cards: " + e.cardManager.count);			
			// Init next step
			initNextStep();
		}
		
		private static function cardManagerLoadFailed(e:CardManagerEvent):void
		{
			// DEBUG > Cardmanager load failed
			if (Logger.canDebug(DEBUG_KEY)) Logger.debug("CardManager failed: " + e.message);
			// Dispatch EVENT_ERROR event
			dispatchApplicationError("Initialization failed, CardManager loading failed: " + e.message);
		}
		
		// AssetManager event handlers
		
		private function assetManagerQueueStart(e:AssetEvent):void
		{
			
		}
		
		private function assetManagerQueueComplete(e:AssetEvent):void
		{
			
		}
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * Initialize the FlashApplication 
		 * @param ui Main UI reference used by the FlashApplication
		 * @param config
		 */
		public static function init(ui:DisplayObject, params:Object = null):void
		{
			// Paramters check
			if (ui == null) throw new Error("FlashApplication must be initialized with a valid root DisplayObject!");
			// Init setup
			_ui = ui;
			_params = params;
			// Begins to initialize the application!
			initBegin();
		}
		
		/**
		 * Executes the login process using given user autentication data. 
		 * @param username
		 * @param password
		 */
		public static function login(username:String, password:String):void
		{
			var message:String = "";
			// Create calls for the sequence
			var call:Call = new Call(CallFactory.CALL_LOGIN, true);
			call.params = { username: username, password: password };
			call.addEventListener(CallEvent.EVENT_CALL_SUCCESS, loginCallSuccessHandler);
			call.addEventListener(CallEvent.EVENT_CALL_ERROR, loginCallErrorHandler);
			call.addEventListener(CallEvent.EVENT_CALL_FAIL, loginCallFailHandler);
			// Executes the login call
			call.execute();
		}
		
		/**
		 * Logout the current loggd user and clears all the data 
		 */		
		public static function logout(dispatchLogoutEvent:Boolean = true):void
		{
			
			// LT_TODO: Gestire passaggio dati a GameClient e lo stop del GameEngine
			
			// Clears the FlashApplication data
			_collection.unload();
			_user.unload();
			// Dispatch EVENT_LOGOUT event
			if (dispatchLogoutEvent) dispatchApplicationLogout();
			// DEBUG > User logout
			if (Logger.canDebug(DEBUG_KEY)) Logger.info("User {0} logout!", _user.username);
		}
			
		/**
		 * 
		 * @param relativeUrl
		 * @return  
		 */
		public static function getAbsoluteCallUrl(relativeUrl:String):String
		{
			return _config.callsUrl + relativeUrl;
		}
		
		/**
		 * 
		 * @return 
		 */		
		public static function dump():Array
		{ 
			// All dump lines
			var dump:Array = new Array();
			// Decorator
			dump.push("");
			dump.push(formatMessage(NAME.toUpperCase() + " [v " + VERSION + "]", true));
			dump.push(formatMessage(""));
			dump.push(formatMessage("<< CONFIGURATION -------------------------------------"));
			dump.push(formatMessage(""));
			dump = _config.dump(dump, 0);
			dump.push(formatMessage(""));
			dump.push(formatMessage("<< USER ----------------------------------------------"));
			dump.push(formatMessage(""));
			dump = _user.dump(dump, 0);
			dump.push(formatMessage(""));
			dump.push(formatMessage("<< COLLECTION ----------------------------------------"));
			dump.push(formatMessage(""));
			dump = _collection.dump(dump, 0);
			// Footer
			dump.push(formatMessage(""));
			dump.push(formatMessage(NAME.toUpperCase() + " [v " + VERSION + "]", true));
			dump.push("");
			// returns the whole dump
			return dump;
		}
		
		/**
		 * 
		 * @param type
		 * @param listener
		 * @param useCapture
		 * @param priority
		 * @param useWeakReference 
		 */		
		public static function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			_dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		
		/**
		 * 
		 * @param type
		 * @return 
		 */		
		public static function hasEventListener(type:String):Boolean
		{
			return _dispatcher.hasEventListener(type);
		}
		
		/**
		 * 
		 * @param type
		 * @param listener
		 * @param useCapture 
		 */		
		public static function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			_dispatcher.removeEventListener(type, listener, useCapture);
		}
		
		/**
		 * 
		 * @param type
		 * @return  
		 */		
		public static function willTrigger(type:String):Boolean
		{
			return _dispatcher.willTrigger(type);
		}
		
	}
}